#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFileDialog>
#include <QTreeWidgetItem>
#include <QLabel>
#include <QSpinBox>
#include <QPixmap>

void MainWindow::changeItemCaption(QTreeWidgetItem *item)
{
    QString str = "*" + item->text(static_cast<int>(colItem));
    item->setText(static_cast<int>(colItem), str);
    if (item->childCount() > 0) {
        for (int i = 0; i < item->childCount(); ++i) {
            changeItemCaption(item->child(i));
        }
    }
}

void MainWindow::displayImage(QTreeWidgetItem *item)
{
    QString fileName = item->data(static_cast<int>(colItem), Qt::UserRole).toString();
    labFileName->setText(fileName);
    labNodeText->setText(item->text(static_cast<int>(colItem)));
    m_pixmp.load(fileName);
    ui->actZoomFitWidth->trigger();
//    ui->actZoonFitHeight->trigger();

    ui->actZoomFitWidth->setEnabled(true);
    ui->actZoomFitHeight->setEnabled(true);
    ui->actZoomIn->setEnabled(true);
    ui->actZoomOut->setEnabled(true);
    ui->actActualSize->setEnabled(true);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->treeWidget->clear();

    // clear()并不会清除表头, 所以需要新建一个并替代之
    QTreeWidgetItem *header = new QTreeWidgetItem();
    header->setText(static_cast<int>(colItem), "目录和文件");
    header->setText(static_cast<int>(colItemType), "节点类型");
    header->setText(static_cast<int>(colDate), "最后的修改日期");

    header->setTextAlignment(static_cast<int>(colItem), Qt::AlignHCenter | Qt::AlignVCenter);
    header->setTextAlignment(static_cast<int>(colItemType), Qt::AlignHCenter | Qt::AlignVCenter);

    ui->treeWidget->setHeaderItem(header);

    // 添加一个根节点
    QIcon icon(":/images/icons/directory.png");
    QTreeWidgetItem *topItem = new QTreeWidgetItem(static_cast<int>(itTopItem));
    topItem->setIcon(static_cast<int>(colItem), icon);
    topItem->setText(static_cast<int>(colItem), "根节点");
    topItem->setText(static_cast<int>(colItemType), "Top Item");
    topItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled
                      | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate);
    topItem->setCheckState(static_cast<int>(colItem), Qt::Checked);

    ui->treeWidget->addTopLevelItem(topItem);

    // status bar
    labNodeText = new QLabel("节点标题", this);
    labNodeText->setMinimumWidth(200);
    ui->statusbar->addWidget(labNodeText);

    spinRatio = new QSpinBox(this);
    spinRatio->setRange(0, 2000);
    spinRatio->setValue(100);
    spinRatio->setSuffix(" %");
    spinRatio->setReadOnly(true);
    spinRatio->setButtonSymbols(QAbstractSpinBox::NoButtons);
    ui->statusbar->addPermanentWidget(spinRatio);

    labFileName = new QLabel("文件名", this);
    ui->statusbar->addPermanentWidget(labFileName);

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_actAddFolder_triggered()
{
    QString dir = QFileDialog::getExistingDirectory();
    if (dir.isEmpty()) {
        return;
    }

    QTreeWidgetItem *parentItem = ui->treeWidget->currentItem();
    if (!parentItem)
        return;

    if (parentItem->type() != static_cast<int>(itImageItem)) { // non-image can add sub item
        int cnt = dir.length();
        int i = dir.lastIndexOf("/");
        QString nodeName = dir.right(cnt - i -1); // file name or folder name, not contain path

        QTreeWidgetItem *item = new QTreeWidgetItem(static_cast<int>(itGroupItem));
        QIcon icon(":/images/icons/directory.png");
        item->setIcon(static_cast<int>(colItem), icon);
        item->setText(static_cast<int>(colItem), nodeName);
        item->setText(static_cast<int>(colItemType), "Group Item");
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled
                       | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate);
        item->setCheckState(static_cast<int>(colItem), Qt::Checked);
        item->setData(static_cast<int>(colItem), Qt::UserRole, QVariant(dir));

        parentItem->addChild(item);
    }
}


void MainWindow::on_actAddFile_triggered()
{
    QStringList files = QFileDialog::getOpenFileNames(this, "选择文件");
    if (files.isEmpty()) {
        return;
    }

    QTreeWidgetItem *parentItem, *curItem;
    curItem = ui->treeWidget->currentItem();
    if (!curItem) { // default: root item
        curItem = ui->treeWidget->topLevelItem(0);
    }

    if (curItem->type() == static_cast<int>(itImageItem)) {
        parentItem = curItem->parent();
    }
    else {
        parentItem = curItem;
    }

    for (int i = 0; i < files.size(); ++i) {
        QString fileName = files[i];
        QIcon icon(":/images/icons/image.png"); //TODO: add icon
        QFileInfo fileInfo(fileName);
        QString nodeText = fileInfo.fileName();
        QDateTime dateTime = fileInfo.lastModified();
        QTreeWidgetItem *item = new QTreeWidgetItem(static_cast<int>(itImageItem));
        item->setIcon(static_cast<int>(colItem), icon);
        item->setText(static_cast<int>(colItem), nodeText);
        item->setText(static_cast<int>(colItemType), "Image Item");
        item->setText(static_cast<int>(colDate), dateTime.toString("yyyy-MM-dd"));
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled
                       | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate);
        item->setCheckState(static_cast<int>(colItem), Qt::Checked);
        item->setData(static_cast<int>(colItem), Qt::UserRole, QVariant(fileName));

        parentItem->addChild(item);
    }
    parentItem->setExpanded(true);
}


void MainWindow::on_actDeleteItem_triggered()
{
    QTreeWidgetItem *curItem = ui->treeWidget->currentItem();
    if (!curItem) {
        return;
    }

    QTreeWidgetItem *parentItem = curItem->parent();
    parentItem->removeChild(curItem);
}


void MainWindow::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
    if (!current || current == previous)
        return;

    switch(current->type()) {
    case static_cast<int>(itTopItem):
        ui->actAddFolder->setEnabled(true);
        ui->actAddFile->setEnabled(true);
        ui->actDeleteItem->setEnabled(false);
        break;
    case static_cast<int>(itGroupItem):
        ui->actAddFolder->setEnabled(true);
        ui->actAddFile->setEnabled(true);
        ui->actDeleteItem->setEnabled(true);
        break;
    case static_cast<int>(itImageItem):
        ui->actAddFolder->setEnabled(false);
        ui->actAddFile->setEnabled(true);
        ui->actDeleteItem->setEnabled(true);
        displayImage(current);
        break;
    default:
        // unknown type
        ;
    }
}


void MainWindow::on_actScanItems_triggered()
{
    // 从最顶层节点开始遍历树所有节点
    for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) {
        changeItemCaption(ui->treeWidget->topLevelItem(i));
    }
}


void MainWindow::on_actZoomFitWidth_triggered()
{
    int width = ui->scrollArea->width() - 30;
    int realWidth = m_pixmp.width();
    m_ratio = static_cast<float>(width) / realWidth;

    spinRatio->setValue(m_ratio * 100);
    QPixmap pix = m_pixmp.scaledToWidth(width - 30);
    ui->labPic->setPixmap(pix);
}


void MainWindow::on_actZoomFitHeight_triggered()
{
    int height = ui->scrollArea->height() - 30;
    int realHeight = m_pixmp.height();
    m_ratio = static_cast<float>(height) / realHeight;

    spinRatio->setValue(m_ratio * 100);
    QPixmap pix = m_pixmp.scaledToHeight(height - 30);
    ui->labPic->setPixmap(pix);
}

void MainWindow::on_actActualSize_triggered()
{
    ui->labPic->setPixmap(m_pixmp);
    m_ratio = 1;
    spinRatio->setValue(m_ratio * 100);
}


void MainWindow::on_actZoomIn_triggered()
{
    m_ratio *= 1.2;
    int width = m_ratio * m_pixmp.width();
    int height = m_ratio * m_pixmp.height();
    ui->labPic->setPixmap(m_pixmp.scaled(width, height));

    spinRatio->setValue(m_ratio * 100);
}


void MainWindow::on_actZoomOut_triggered()
{
    m_ratio *= 0.8;
    int width = m_ratio * m_pixmp.width();
    int height = m_ratio * m_pixmp.height();
    ui->labPic->setPixmap(m_pixmp.scaled(width, height));

    spinRatio->setValue(m_ratio * 100);
}


void MainWindow::on_actDockVisible_triggered(bool checked)
{
    ui->dockWidget->setVisible(checked);
}


void MainWindow::on_actDockFloat_triggered(bool checked)
{
    ui->dockWidget->setFloating(checked);
}


void MainWindow::on_dockWidget_visibilityChanged(bool visible)
{
    ui->actDockVisible->setChecked(visible);
}


void MainWindow::on_dockWidget_topLevelChanged(bool topLevel)
{
    ui->actDockFloat->setChecked(topLevel);
}

